package com.microservices.yucloud.appweb.disruptor;

import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.YieldingWaitStrategy;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.Executors;

/**
 * @author zy
 * @date 2019-09-05 20:05
 **/
@Slf4j
@Service
public class OrderEventProducer {

    @Autowired
    private OrderEventConsumer orderEventConsumer;

    private Disruptor<OrderEvent> disruptor;
    private static final int RING_BUFFER_SIZE = 1024 * 1024;

    @PreDestroy
    public void destroy() {
        disruptor.shutdown();
    }

    @PostConstruct
    public void init() {
        disruptor = new Disruptor<>(new OrderEventFactory(), RING_BUFFER_SIZE, Executors.defaultThreadFactory(), ProducerType.SINGLE, new YieldingWaitStrategy());
        disruptor.handleEventsWith(orderEventConsumer);
        disruptor.setDefaultExceptionHandler(new OrderEventHandlerException());
        disruptor.start();
    }


    public void send(String bizCode, String message) {
        RingBuffer<OrderEvent> ringBuffer = disruptor.getRingBuffer();
        ringBuffer.publishEvent((event, sequence, arg0, arg1) -> {
            event.setBizCode(arg0);
            event.setOrder(arg1);
        }, bizCode, message);
//        ringBuffer.publishEvent((event, sequence, data) -> event.setOrder(data), message);
    }
}
